package name.weily.liba.tools

import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.*
import retrofit2.converter.scalars.ScalarsConverterFactory

class RetrofitUtil {
    companion object {
        var httpLogLevel: HttpLoggingInterceptor.Level? = null
        var converterFactory: Converter.Factory? = null

        private var retrofit: Retrofit? = null

        fun get(baseUrl: String) : Retrofit {
            return retrofit ?: synchronized(this) {
                return retrofit?.apply {
                    return@synchronized if (baseUrl().toString() == baseUrl) retrofit
                    else build(baseUrl).apply { retrofit = this }
                } ?: build(baseUrl).apply { retrofit = this }
            }
        }

        private fun build(base: String) : Retrofit {
            val client = OkHttpClient().newBuilder()
                .addInterceptor(HttpLoggingInterceptor().setLevel(httpLogLevel ?: HttpLoggingInterceptor.Level.BASIC))
                .build()
            return Retrofit.Builder().baseUrl(base)
                .client(client)
                .addConverterFactory(converterFactory ?: ScalarsConverterFactory.create()).build()
        }
    }

    inline fun <reified T> getService(clazz: Class<T>, baseUrl: String) : T {
        return get(baseUrl).create(T::class.java)
    }
}


typealias callback<T> = ((T?, error: String?) ->Unit)
typealias callbackWithCode<T> = ((Int, T?, error: String?) ->Unit)

class SimpleNetCallback<T>(val callback: callback<T>) : Callback<T> {

    override fun onResponse(call: Call<T>, response: Response<T>) {
        callback(response.body(), "${response.code()}")
    }

    override fun onFailure(call: Call<T>, t: Throwable) {
        callback(null, t.localizedMessage)
    }
}

class SimpleNetCallbackCode<T>(val callback: callbackWithCode<T>) : Callback<T> {

    override fun onResponse(call: Call<T>, response: Response<T>) {
        callback(response.code(), response.body(), null)
    }

    override fun onFailure(call: Call<T>, t: Throwable) {
        callback(-1, null, t.localizedMessage)
    }
}
